<?php

namespace common\observer;

use common\model\EntityModel;
use common\model\ModuleModel;
use common\model\TaskModel;
use support\SingletonTrait;
use Webman\Stomp\Client;
use teamones\dbeventObserver\interfaces\SplObserver;
use teamones\dbeventObserver\interfaces\SplSubject;

class CheckRepairAffectedTaskIsAbnormal implements SplObserver
{
    use SingletonTrait;

    /**
     * @inheritDoc
     */
    function update(SplSubject $subject): void
    {
        $updateData = $subject->getSplUpdateData();
        if (!isset($updateData['is_publish']) || $updateData['is_publish'] !== 'yes') {
            return;
        }
        $version = $subject->getSubjectData();
        if ($version["module_id"] != module_by_code("task")["id"]) {
            return;
        }
        $taskData = model(TaskModel::class)->where(['step_type' => 'step', 'id' => $version['link_id']])->find();
        if (empty($taskData)) {
            return;
        }
        $entityId = 0;
        $designModuleData = module_by_code('design');
        $storyboardModuleData = module_by_code('storyboard');
        $entityData = model(EntityModel::class)->where(['id' => $taskData['entity_id']])->find();
        // 找到有关这个实体的所有上/下游
        $entityList = model(EntityModel::class)
            ->field("entity.id, entity.module_id, json_extract(entity.json, concat('$.', m.code, '_is_abnormal')) as is_abnormal")
            ->join('module m on m.id = entity.module_id')
            ->where([
                'entity.code' => $entityData['code'],
                'entity.project_id' => $entityData['project_id'],
                'entity.initial_episode_code' => $entityData['initial_episode_code'],
                'entity.showings_number' => $entityData['showings_number']
            ])
            ->select();
        foreach ($entityList as $entityItem) {
            if ($entityItem['is_abnormal'] == 'no') {
                return;
            }
            if ($entityItem['module_id'] == $designModuleData['id'] || $entityItem['module_id'] == $storyboardModuleData['id']) {
                $entityId = $entityItem['id'];
            }
        }
        if ($entityId == 0) {
            return;
        }
        $entityIds = array_column($entityList, 'id');
        $taskList = model(TaskModel::class)->where(['entity_id' => ['IN', $entityIds]])->select();
        // 获取该实体有多少个工序类型
        foreach ($taskList as $taskItem) {
            if ($taskItem['step_type'] == 'step_category') {
                $taskStepCategoryFilter[0][]['step_category_id'] = $taskItem['step_category_id'];
            }
        }
        $taskStepCategoryFilter[0]['_logic'] = 'or';
        $taskStepCategoryFilter[] = [
            'step_type' => 'step',
            'entity_id' => ['IN', $entityIds]
        ];
        // 获取每个工序下的最后一条工序任务
        $taskList = model(TaskModel::class)
            ->where($taskStepCategoryFilter)
            ->field('max(id) as id,entity_id,step_category_id,plan_end_time,end_time')
            ->group('entity_id,step_category_id')
            ->select();
        foreach ($taskList as $taskItem) {
            // 如果有完成时间但是大于计划完成时间，就代表有逾期完成，返回false
            if (($taskItem['plan_end_time'] > 0 && $taskItem['end_time'] > $taskItem['plan_end_time']) || ($taskItem['plan_end_time'] > 0 && $taskItem['plan_end_time'] < time() && $taskItem['end_time'] = 0)) {
                return;
            }
        }
        model(EntityModel::class)->execute("UPDATE entity join module m on m.id = entity.module_id SET json = JSON_SET(IFNULL(json, '{}'), concat('$.',m.code, '_is_abnormal'), 'no') where entity.id = {$entityId}");
    }

}
